package com.heu.blood.security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.common.Constant.UserConstantData;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.security.dao.UserDao;
import com.heu.blood.security.dictenum.LoginStateEnum;
import com.heu.blood.security.entity.UserEntity;
import com.heu.blood.security.exception.UserLoginException;
import com.heu.blood.security.service.UserService;
import com.heu.blood.security.vo.UserVo;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Base64;
import java.util.List;
import java.util.Map;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
    // 添加这一行
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserDao userDao;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 分页查询登录用户信息
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        // 构造UserEntity对象去接收那些参数
        UserEntity userEntity = new UserEntity();
        if (Strings.isNotBlank((String) params.get("userName"))){
            userEntity.setUserName((String) params.get("userName")); // 用户名
        }
        if (Strings.isNotBlank((String) params.get("status"))){
            userEntity.setStatus((String) params.get("status")); // 状态
        }
        if (Strings.isNotBlank((String) params.get("userType"))){
            userEntity.setUserType((String) params.get("userType")); // 用户类型
        }
        if (Strings.isNotBlank((String) params.get("sex"))){
            userEntity.setSex((String) params.get("sex")); // 性别
        }
        // 构造queryWrapper
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(userEntity.getUserName()), UserEntity::getUserName, userEntity.getUserName())
                    .eq(Strings.isNotBlank(userEntity.getStatus()), UserEntity::getStatus, userEntity.getStatus())
                    .eq(Strings.isNotBlank(userEntity.getUserType()), UserEntity::getUserType, userEntity.getUserType())
                    .eq(Strings.isNotBlank(userEntity.getSex()), UserEntity::getSex, userEntity.getSex());
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    /**
     * 保存用户信息
     * @param userEntity
     */
    @Override
    public String saveUser(UserEntity userEntity) {
        String msg = "保存成功";
        if (Strings.isNotBlank(userEntity.getUserName())){
            // 检查是否有同名用户
            Integer duplicateUserNameCount = this.userNameDuplicateCheck(userEntity.getUserName());
            if (duplicateUserNameCount != 0){
                // 有同名用户则加上递增数字进行区分
                String newName = userEntity.getUserName() + String.format("%02d", duplicateUserNameCount + 1);
                userEntity.setUserName(newName);
                msg += "，该用户已注册，已更改为：" + newName;
            }
        }
        // 主要是针对密码进行一个加密操作
        if (Strings.isNotBlank(userEntity.getPassword())){
            // 如果传过来的密码不为空，则进行加密
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
        }
        this.save(userEntity);
        return msg;
    }

    /**
     * 修改用户信息
     * @param userEntity
     */
    @Override
    public String updateUserById(UserEntity userEntity) {
        String msg = "更新成功";
        if (Strings.isNotBlank(userEntity.getUserName())){
            // 检查是否有同名用户
            Integer duplicateUserNameCount = this.userNameDuplicateCheck(userEntity.getUserName());
            if (duplicateUserNameCount != 0){
                // 有同名用户则加上递增数字进行区分
                String newName = userEntity.getUserName() + String.format("%02d", duplicateUserNameCount + 1);
                userEntity.setUserName(newName);
                msg += "，该用户已注册，已更改为：" + newName;
            }
        }
        // 主要是针对密码进行一个加密操作
        if (Strings.isNotBlank(userEntity.getPassword())){
            // 如果传过来的密码不为空，则进行加密
            userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
        }
        this.updateById(userEntity);
        return msg;
    }

    /**
     * 根据用户名进行查找
     * @param userName
     * @return
     */
    @Override
    public Integer userNameDuplicateCheck(String userName) {
        // 构造queryWrapper
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件
        queryWrapper.like(Strings.isNotBlank(userName), UserEntity::getUserName, userName);
        // 进行查询
        List<UserEntity> userEntities = userDao.selectList(queryWrapper);
        int count = 0;
        for (UserEntity userEntity : userEntities){
            if (userName.equals(userEntity.getUserName().replaceAll("\\d", ""))){
                count++;
            }
        }
        return count;
    }

    @Override
    public String testLogin(String username, String password) {
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(username), UserEntity::getUserName, username);
        UserEntity userEntity = userDao.selectOne(queryWrapper);
        if(userEntity == null){
            throw new MyException(UserLoginException.NO_USER);
        }
        boolean passwordMatches = passwordEncoder.matches(password, userEntity.getPassword());
        if(!passwordMatches){
            throw new MyException(UserLoginException.PASSWORD_ERROR);
        }
        return LoginStateEnum.SUCCESS_LOGIN.code();
    }

    @Override
    public int setSignUrl(UserVo user) {

        // 获取当前系统对应的签名图片保存路径
        String signPath = UserConstantData.getSignUrlPath();
        log.info("签名保存路径: " + signPath);
        log.info("当前操作系统: " + System.getProperty("os.name"));
        
        // 确保目录存在
        File directory = new File(signPath);
        log.info("目录是否存在: " + directory.exists());
        log.info("目录绝对路径: " + directory.getAbsolutePath());
        if (!directory.exists()) {
            boolean created = directory.mkdirs();
            if (!created) {
                log.error("无法创建签名图片目录: " + signPath);
                return 1;
            }
        }
        // 检查目录权限
        log.info("目录是否可读: " + directory.canRead());
        log.info("目录是否可写: " + directory.canWrite());
        log.info("目录是否可执行: " + directory.canExecute());

        // 指定文件夹路径和要删除的文件名
        String deleteFileName = user.getUserId() + ".png";

        // 创建File对象
        File deleteFile = new File(signPath, deleteFileName);

        // 检查文件是否存在
        if (deleteFile.exists()) {
            // 删除文件
            boolean isDeleted = deleteFile.delete();
            if (isDeleted) {
                log.warn("文件已被删除");
            } else {
                log.warn("文件删除失败");
            }
        } else {
            log.warn("文件不存在");
        }

        Base64.Decoder decoder = Base64.getDecoder();
        // 去掉base64前缀 data:image/jpeg;base64,
        String file = user.getPicBase64();
        file = file.substring(file.indexOf(",", 1) + 1, file.length());
        byte[] b = decoder.decode(file);
        // 处理数据
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        // 图片名称为用户userId加上png
        String savePath = signPath + user.getUserId() + ".png";
        // 保存图片
        OutputStream out = null;
        try {
            out = new FileOutputStream(savePath);
            out.write(b);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return 1;
        } catch (IOException e) {
            return 1;
        }
        // 设置一下当前用户的签名照，根据用户名来的，所以注册的时候需要注意名称别重了
        LambdaUpdateWrapper<UserEntity> updateWrapper = new LambdaUpdateWrapper<>();
        String curSingUrl = user.getUserId() + ".png";
        user.setSignUrl(curSingUrl);
        updateWrapper.set(UserEntity::getSignUrl,user.getSignUrl())
                .eq(UserEntity::getUserId,user.getUserId());
        this.update(updateWrapper);
        return 0;
    }
}